﻿using System;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace YanMsg.APCode
{
    /// <summary>
    /// 在WPF的TextBox中显式显示提示信息
    /// </summary>
    public class TextBoxPlus : TextBox
    {
        /// <summary>
        /// 显式显示的提示信息
        /// </summary>
        public String ExplicitToolTip { get; set; }
 
        /// <summary>
        /// 提示信息的文字颜色，默认为黑灰色
        /// </summary>
        protected Brush _ToolTipForeground = Brushes.DarkGray;
        public Brush ToolTipForeground
        {
            get { return _ToolTipForeground; }
            set
            {
                _ToolTipForeground = value;
                if (base.Foreground != _NormalForeground)
                {   // 处于提示状态，更新提示内容颜色
                    base.Foreground = value;    // 更新文本颜色
                }
            }
        }
 
        /// <summary>
        /// 正常内容的文字颜色，默认为黑色
        /// </summary>
        /// <remarks>
        /// 注意：Foreground 被 NormalForeground 替换
        /// </remarks>
        protected Brush _NormalForeground = Brushes.Black;
        public Brush NormalForeground
        {
            get { return _NormalForeground; }
            set
            {
                _NormalForeground = value;
                if (base.Foreground != _ToolTipForeground)
                {   // 处于正常状态，更新正常内容颜色
                    base.Foreground = value; 
                }
            }
        }
 
        /// <summary>
        /// 获取或设置一个用于描述前景色的画笔
        /// </summary>
        /// <remarks>隐藏继承成员</remarks>
        protected new Brush Foreground
        {
            get { return base.Foreground; }
            set { base.Foreground = value; }
        }
 
        /// <summary>
        /// 获取或设置文本框的文本内容
        /// </summary>
        /// <remarks>隐藏继承成员</remarks>
        public new String Text 
        {
            get
            { 
                if (base.Foreground == _ToolTipForeground)
                    return String.Empty;    // 提示状态
                else
                    return base.Text;       // 正常状态
            }
            set
            {
                base.Text = value;
            }
        }
 
        /// <summary>
        /// 文本框初始内容为空时，设置提示信息
        /// </summary>
        /// <param name="e">事件数据</param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
 
            // 设置文本颜色
            base.Foreground = _NormalForeground;
 
            // 触发文本改变事件
            if (String.IsNullOrEmpty(base.Text))
            {   // 显示提示信息
                base.Text = ExplicitToolTip;  // 注意：引发新的 TextChanged 事件
 
                // 更换字体颜色
                base.Foreground = _ToolTipForeground;
            }
        }
 
        /// <summary>
        /// 当用户每次开始输入时，清除提示信息
        /// </summary>
        /// <param name="e">事件数据</param>
        protected override void OnPreviewTextInput(TextCompositionEventArgs e)
        {   // 通过字体颜色判断文本框状态
            if (base.Foreground == _ToolTipForeground)
            {   // 更换字体颜色
                base.Foreground = _NormalForeground;
 
                // 直接把提示信息更新为用户输入内容
                base.Text = e.Text;    // 注意：引发TextChanged事件
 
                // 调整插入位置到最后，否则光标会在最前面
                base.SelectionStart = e.Text.Length;
 
                // 标记消息已处理
                e.Handled = true;
            }
        }
 
        /// <summary>
        /// 当文本框内容为空时，显示提示信息
        /// </summary>
        /// <param name="e">事件数据</param>
        /// <remarks>
        /// 注意：粘帖操作不会触发 PreviewTextInput 事件
        /// </remarks>
        protected override void OnTextChanged(TextChangedEventArgs e)
        {   // 文本框内容为空
            if (String.IsNullOrEmpty(base.Text))
            {   // 显示提示信息
                base.Text = ExplicitToolTip;  // 注意：引发新的 TextChanged 事件
 
                // 设置插入位置在最前面
                base.SelectionStart = 0;
 
                // 更换字体颜色
                base.Foreground = _ToolTipForeground;
 
                // 标记消息已处理
                e.Handled = true;
            }
            else if (base.Foreground != _NormalForeground)
            {   // 粘帖操作触发 TextChanged 事件
                System.Text.StringBuilder sb = new System.Text.StringBuilder(base.MaxLength);
                foreach (TextChange item in e.Changes)
                {   // 获取粘帖的文字内容
                    if (item.AddedLength > 0)
                    {
                        sb.Append(base.Text.Substring(item.Offset, item.AddedLength));
                    }
                }
 
                if (sb.Length > 0)
                {   // 改为正常字体颜色
                    base.Foreground = _NormalForeground;
 
                    // 显示增加的文字内容
                    base.Text = sb.ToString();     // 注意：引发新的 TextChanged 事件
 
                    // 调整插入位置到最后，否则光标会在最前面
                    base.SelectionStart = sb.Length;
                }
 
                // 标记消息已处理
                e.Handled = true;
            }
        }
    }
}